<?php


namespace Yunkeweb\Weather;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Yunkeweb\Weather\Exceptions\HttpException;
use Yunkeweb\Weather\Exceptions\InvalidArgumentException;

class Weather
{
    protected string $key;
    protected array $guzzleOptions = [];

    public function __construct(string $key)
    {
        $this->key = $key;
    }

    public function getHttpClient(): Client
    {
        return new Client($this->guzzleOptions);
    }

    public function setGuzzleOptions(array $options): void
    {
        $this->guzzleOptions = $options;
    }

    /**
     * @throws GuzzleException
     * @throws InvalidArgumentException
     * @throws HttpException
     */
    public function getWeather($city, string $type = 'base', string $format = 'json')
    {
        $url = 'https://restapi.amap.com/v3/weather/weatherInfo';

        $types = [
            'live' => 'base',
            'forecast' => 'all',
        ];

        if (!\in_array(\strtolower($format),['xml','json'])){
            throw new InvalidArgumentException(sprintf("Invalid response format: %s",$format));
        }

        if (!\in_array(\strtolower($type),['base','all'])){
            throw new InvalidArgumentException(sprintf("Invalid type value(base/all): %s",$type));
        }

        $query = array_filter([
            'key' => $this->key,
            'city' => $city,
            'output' => $format,
            'extensions' => $type
        ]);

        try {
            $response = $this->getHttpClient()->get($url,[
                'query' => $query
            ])->getBody()->getContents();

            return 'json' === $format ? \json_decode($response,true) : $response;
        }catch (\Exception $e){
            throw new HttpException($e->getMessage(),$e->getCode(),$e);
        }
    }

    /**
     * @throws HttpException
     * @throws GuzzleException
     * @throws InvalidArgumentException
     */
    public function getLiveWeather($city, $format = 'json')
    {
        return $this->getWeather($city, 'base', $format);
    }

    /**
     * @throws HttpException
     * @throws GuzzleException
     * @throws InvalidArgumentException
     */
    public function getForecastsWeather($city, $format = 'json')
    {
        return $this->getWeather($city, 'all', $format);
    }
}